`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/12/17 15:25:18
// Design Name: 
// Module Name: fifo_8to4
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module fifo_8to4(clk,rstn,data_in,readp,writep,cnt);
input		clk;
input		rstn; 
input [7:0]	data_in;
input		readp;   
input		writep;    
reg 	fifo_empty;
reg	    fifo_full;
reg     r;
reg [3:0]data_out;               
reg [2:0]addr;
output reg [4:0] cnt;
reg [7:0] mem[7:0];

always @(posedge clk) begin
   if (rstn) begin
      data_out <= 8'h00;    
      r <= 0;
   end
   else if(!rstn && readp &&!r)begin
      data_out <= mem[addr][3:0];
      r=1;
   end
   else if(!rstn && readp &&r)begin
   data_out <= mem[addr][7:4];
   r=0;
   end
end 
always @(posedge clk) begin
   if (!rstn&&writep&& fifo_full == 1'b0 && r==0) begin
      mem[addr]<= data_in; 
      end
   end
always @(posedge clk) begin
   if (rstn == 1'b1) begin
      addr <= 2'b000;          
   end
   else begin
      if (!rstn &&writep&&!fifo_full) begin
         addr <= addr + 1;
      end
   end
end

always @(posedge clk) begin
   if (rstn == 1'b1) begin
      cnt <= 4'b0000;
      r = 0;
   end
   else begin
      case ({readp, writep})
         2'b00: cnt <= cnt;
         2'b01: 
   if (cnt!=15 && cnt!= 16) begin
               cnt <= cnt + 2; 
               end
         2'b10: 
            if (cnt != 0) begin
               cnt <= cnt - 1;
               end
         2'b11:
           cnt <= cnt+1;
      endcase
   end
end
always @(cnt)
   if (cnt == 0)begin
      fifo_empty <= 1'b1;
      end
   else begin
      fifo_empty <= 1'b0;
      end
always @(cnt) 
   if (cnt == 16) begin
      fifo_full <= 1'b1;
      end
   else begin
      fifo_full <= 1'b0;
end
endmodule
